<template>
  <div class="app-container message-center">
    <el-row :gutter="20">
      <el-col :span="6">
        <div class="grid-content">
          <title-view title="MQ节点" />
          <div class="app-container list-container">
            <template v-if="mqList.length">
              <div
                class="list-container-item"
                :class="{ 'active-item': activeMqItemId === item.id }"
                :key="item.id"
                v-for="item in mqList"
              >
                <div class="list-container-item__label" @click="changeMqActive(item)">
                  <span v-ellipsis="{ rows: 1, text: item.label }"></span>
                </div>
                <div class="list-container-item__buttons">
                  <!--                  <el-button type="primary" :icon="Edit" link @click="handelAddNode('MQ', true, item)"></el-button>-->
                  <el-button type="danger" :icon="Delete" link @click="deleteNodeItem(item, '', '')"></el-button>
                </div>
              </div>
            </template>
            <el-empty v-else />
          </div>
          <el-button class="add-node-button" type="primary" size="large" :icon="Plus" @click="handelAddNode('MQ')"
            >添加MQ节点</el-button
          >
        </div>
      </el-col>
      <el-col :span="6">
        <div class="grid-content">
          <title-view title="服务节点" />
          <div class="app-container list-container">
            <template v-if="mqList.length && serviceList.length">
              <div
                class="list-container-item"
                :class="{ 'active-item': activeServiceItemId === item.id }"
                :key="item.id"
                v-for="item in serviceList"
              >
                <div class="list-container-item__label" @click="changeServiceActive(item)">
                  <span v-ellipsis="{ rows: 1, text: item.label }"></span>
                </div>
                <div class="list-container-item__buttons">
                  <!--                  <el-button type="primary" :icon="Edit" link @click="handelAddNode('SERVER', true, item)"></el-button>-->
                  <el-button type="danger" :icon="Delete" link @click="deleteNodeItem(item, activeMqItemId, 'MQ')"></el-button>
                </div>
              </div>
            </template>
            <el-empty v-else />
          </div>
          <el-button
            class="add-node-button"
            type="primary"
            size="large"
            :icon="Plus"
            :disabled="activeMqItemId === -1"
            @click="handelAddNode('SERVER')"
            >添加服务节点</el-button
          >
        </div>
      </el-col>
      <el-col :span="6">
        <div class="grid-content">
          <title-view title="事件节点" />
          <div class="app-container list-container">
            <template v-if="serviceList.length && eventList.length">
              <div
                class="list-container-item"
                :class="{ 'active-item': activeEventItemId === item.id }"
                :key="item.id"
                v-for="item in eventList"
              >
                <div class="list-container-item__label" @click="changeEventActive(item)">
                  <span v-ellipsis="{ rows: 1, text: item.label }"></span>
                </div>
                <div class="list-container-item__buttons">
                  <!--                  <el-button type="primary" :icon="Edit" link @click="handelAddNode('EVENT', true, item)"></el-button>-->
                  <el-button
                    type="danger"
                    :icon="Delete"
                    link
                    @click="deleteNodeItem(item, activeServiceItemId, 'SERVER')"
                  ></el-button>
                </div>
              </div>
            </template>
            <el-empty v-else />
          </div>
          <el-button
            class="add-node-button"
            type="primary"
            size="large"
            :icon="Plus"
            :disabled="activeServiceItemId === -1"
            @click="handelAddNode('EVENT')"
            >添加事件节点</el-button
          >
        </div>
      </el-col>
      <el-col :span="6">
        <div class="grid-content">
          <title-view title="消费者节点" />
          <div class="app-container list-container">
            <template v-if="eventList.length && customerList.length">
              <div class="list-container-item" v-for="item in customerList" :key="item.id">
                <div class="list-container-item__label">
                  <span v-ellipsis="{ rows: 1, text: item.label }"></span>
                </div>
                <div class="list-container-item__buttons">
                  <!--                  <el-button type="primary" :icon="Edit" link @click="handelAddNode('CUSTOMER_QUEUE', true, item)"></el-button>-->
                  <el-button
                    type="danger"
                    :icon="Delete"
                    link
                    @click="deleteNodeItem(item, activeEventItemId, 'EVENT')"
                  ></el-button>
                </div>
              </div>
            </template>
            <el-empty v-else />
          </div>
          <el-button
            class="add-node-button"
            type="primary"
            size="large"
            :icon="Plus"
            :disabled="activeEventItemId === -1"
            @click="handelAddNode('CUSTOMER_QUEUE')"
            >添加消费者节点</el-button
          >
        </div>
      </el-col>
    </el-row>

    <!--  添加节点 start -->
    <el-dialog
      v-model="isShowAddDialog"
      title="添加节点"
      width="500"
      :align-center="true"
      :close-on-click-modal="false"
      destroy-on-close
      @close="handelCancel"
    >
      <el-form ref="nodeFormRef" :model="nodeForm" label-width="110px" status-icon>
        <template v-if="['CUSTOMER_QUEUE', 'SERVER'].includes(nodeForm.type)">
          <el-form-item
            label="服务名称"
            prop="nodeName"
            :rules="[{ required: true, message: '请选择服务名称', trigger: 'change' }]"
          >
            <el-select v-model="nodeForm.nodeName" placeholder="请选择" @change="nodeLabelSelectChange">
              <el-option v-for="item in nodeLabelLists" :key="item.serverId" :label="item.serverName" :value="item.serverId" />
            </el-select>
          </el-form-item>
        </template>
        <template v-else>
          <el-form-item
            label="节点名称"
            prop="nodeName"
            :rules="[{ required: true, message: '请输入节点名称', trigger: 'blur' }]"
          >
            <el-input v-model.trim="nodeForm.nodeName" placeholder="请输入" />
          </el-form-item>
          <el-form-item
            label="节点显示名称"
            prop="label"
            :rules="[{ required: true, message: '请输入节点显示名称', trigger: 'blur' }]"
          >
            <el-input v-model.trim="nodeForm.label" placeholder="请输入" />
          </el-form-item>
        </template>
        <template v-if="nodeForm.type === 'MQ'">
          <el-form-item
            label="mqName"
            prop="config.mqName"
            :rules="[{ required: true, message: '请输入mqName', trigger: 'blur' }]"
          >
            <el-input v-model.trim="nodeForm.config.mqName" placeholder="请输入" />
          </el-form-item>
          <el-form-item label="host" prop="config.host" :rules="[{ required: true, message: '请输入host', trigger: 'blur' }]">
            <el-input v-model.trim="nodeForm.config.host" placeholder="请输入" />
          </el-form-item>
          <el-form-item label="port" prop="config.port" :rules="[{ required: true, message: '请输入port', trigger: 'blur' }]">
            <el-input v-model.trim="nodeForm.config.port" placeholder="请输入" />
          </el-form-item>
          <el-form-item
            label="password"
            prop="config.password"
            :rules="[{ required: true, message: '请输入password', trigger: 'blur' }]"
          >
            <el-input v-model.trim="nodeForm.config.password" placeholder="请输入" />
          </el-form-item>
          <el-form-item
            label="username"
            prop="config.username"
            :rules="[{ required: true, message: '请输入username', trigger: 'blur' }]"
          >
            <el-input v-model.trim="nodeForm.config.username" placeholder="请输入" />
          </el-form-item>
          <el-form-item
            label="virtualHost"
            prop="config.virtualHost"
            :rules="[{ required: true, message: '请输入virtualHost', trigger: 'blur' }]"
          >
            <el-input v-model.trim="nodeForm.config.virtualHost" placeholder="请输入" />
          </el-form-item>
        </template>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="handelCancel">取消</el-button>
          <el-button type="primary" @click="handelSubmit">确定</el-button>
        </div>
      </template>
    </el-dialog>
    <!-- 添加节点 end -->
  </div>
</template>

<script setup>
import { ref, getCurrentInstance } from "vue";
import { Delete, Edit, Plus } from "@element-plus/icons-vue";
import _ from "lodash";
import {
  nodeListByParentId,
  nodeListByType,
  createNode,
  updateNode,
  deleteNode,
  nodeLabelList
} from "@/api/messageCenter/index.js";

const { proxy } = getCurrentInstance();

const nodeLabelLists = ref([]);
const getNodeLabelList = async () => {
  const { data } = await nodeLabelList();
  nodeLabelLists.value = data ?? [];
};
const getNodeListByType = async (nodeType = "MQ", parentIdParam) => {
  const fetchNodeData = async (fetchFn, listRef, activeIdRef, parentId) => {
    const { data } = parentId ? await fetchFn(parentId) : await fetchFn();
    listRef.value = data ?? [];
    activeIdRef.value = data?.[0]?.id || -1;
    return data?.[0]?.id || null;
  };
  const flow = [
    { fetchFn: () => nodeListByType("MQ"), type: "MQ", listRef: mqList, activeIdRef: activeMqItemId },
    { fetchFn: nodeListByParentId, type: "SERVER", listRef: serviceList, activeIdRef: activeServiceItemId },
    { fetchFn: nodeListByParentId, type: "EVENT", listRef: eventList, activeIdRef: activeEventItemId },
    { fetchFn: nodeListByParentId, type: "CUSTOMER_QUEUE", listRef: customerList, activeIdRef: activeCustomerItemId }
  ];
  let parentId = parentIdParam ?? null,
    flowApis = [];
  if (!nodeType) {
    flowApis = flow;
  } else {
    const nodeTypeIndex = flow.findIndex(item => item.type === nodeType);
    flowApis = flow.slice(nodeTypeIndex + 1);
  }
  for (const step of flowApis) {
    parentId = await fetchNodeData(step.fetchFn, step.listRef, step.activeIdRef, parentId);
    if (!parentId) break;
  }
};

/**
 * mq列表
 */
const mqList = ref([]);
const activeMqItemId = ref(-1);
const changeMqActive = data => {
  activeMqItemId.value = data.id;
  activeServiceItemId.value = -1;
  activeEventItemId.value = -1;
  activeCustomerItemId.value = -1;
  serviceList.value = [];
  eventList.value = [];
  customerList.value = [];
  getNodeListByType("MQ", data.id);
};
/**
 * 服务列表
 */
const serviceList = ref([]);
const activeServiceItemId = ref(-1);
const changeServiceActive = data => {
  activeServiceItemId.value = data.id;
  eventList.value = [];
  customerList.value = [];
  activeEventItemId.value = -1;
  activeCustomerItemId.value = -1;
  getNodeListByType("SERVER", data.id);
};
/**
 * 事件列表
 */
const eventList = ref([]);
const customerList = ref([]);
const activeEventItemId = ref(-1);
const activeCustomerItemId = ref(-1);
const changeEventActive = data => {
  activeEventItemId.value = data.id;
  activeCustomerItemId.value = -1;
  customerList.value = [];
  getNodeListByType("EVENT", data.id);
};

const deleteNodeItem = (data, parentId, nodeType) => {
  proxy.$modal
    .confirm("确定删除该节点吗？", "提示")
    .then(async () => {
      await deleteNode(data.id);
      getNodeListByType(nodeType, parentId);
      proxy.$modal.msgSuccess("操作成功！");
    })
    .catch(() => {});
};

const isShowAddDialog = ref(false);
const isEdit = ref(false);
const initFormData = {
  id: "",
  nodeName: "",
  label: "",
  type: "", // MQ,SERVER,EVENT,CUSTOMER_QUEUE
  parentId: "",
  idChain: "",
  description: "",
  config: {
    mqName: "",
    host: "",
    port: "",
    password: "",
    username: "",
    virtualHost: ""
  }
};
const nodeForm = ref(_.cloneDeep(initFormData));
const nodeLabelSelectChange = e => {
  const labelObj = nodeLabelLists.value.find(item => item.serverId === e);
  nodeForm.value.label = labelObj?.serverName;
};
const handelAddNode = (nodeType, isEditStatus = false, itemData) => {
  isEdit.value = isEditStatus;
  if (isEditStatus) {
    nodeForm.value = _.cloneDeep(itemData);
    if (nodeType === "MQ") {
      nodeForm.value.config = itemData.config ? JSON.parse(itemData.config) : {};
    }
  } else {
    nodeForm.value.type = nodeType;
    switch (nodeType) {
      case "SERVER":
        nodeForm.value.parentId = activeMqItemId.value;
        break;
      case "EVENT":
        nodeForm.value.parentId = activeServiceItemId.value;
        break;
      case "CUSTOMER_QUEUE":
        nodeForm.value.parentId = activeEventItemId.value;
        break;
      default:
        nodeForm.value.parentId = "";
    }
  }
  getNodeLabelList();
  isShowAddDialog.value = true;
};

const getParentType = nodeType => {
  switch (nodeType) {
    case "MQ":
      return "";
    case "SERVER":
      return "MQ";
    case "EVENT":
      return "SERVER";
    case "CUSTOMER_QUEUE":
      return "EVENT";
    default:
      return "";
  }
};
const handelSubmit = () => {
  proxy.$refs.nodeFormRef.validate(async valid => {
    if (!valid) return;
    const postData = { ...nodeForm.value };
    postData.config = JSON.stringify(postData.config);
    const subApi = isEdit.value ? updateNode : createNode;
    await subApi(postData);
    getNodeListByType(getParentType(postData.type), postData.parentId);
    proxy.$modal.msgSuccess("操作成功！");
    handelCancel();
  });
};
const handelCancel = () => {
  nodeForm.value = _.cloneDeep(initFormData);
  isShowAddDialog.value = false;
};

getNodeListByType("");
</script>
<style lang="scss" scoped>
.message-center {
  height: calc(100vh - 85px);
  .el-row {
    height: 100%;
    .el-col {
      height: 100%;
    }
  }
}
.grid-content {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  height: 100%;
  border: 1px solid #f0f2f5;
  border-radius: 10px;
  :deep(.title-container) {
    padding: 20px 20px 0 20px;
  }
  .list-container {
    position: relative;
    flex: 1;
    overflow-y: auto;
    &-item {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 15px 20px;
      cursor: pointer;
      border-radius: 4px;
      &__label {
        width: 100%;
      }
      &__buttons {
        display: flex;
        align-items: center;
      }
      & + .list-container-item {
        margin-top: 10px;
      }
      &:hover {
        color: #007dff;
        background-color: #d9e8ff;
      }
    }
    .active-item {
      color: #007dff;
      background-color: #d9e8ff;
    }
    :deep(.el-empty) {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
    }
  }
  .add-node-button {
    width: 200px;
    margin: 20px auto;
  }
  ::-webkit-scrollbar {
    width: 0;
  }
}
</style>
